/*
 * psm.h
 *
 *  Created on: 2022.12.28
 *      Author: hello
 */

#ifndef PSM_H_
#define PSM_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>

typedef enum
{
    PSM_UNPACK_ENCODE_BY_NONE          = 0,
    PSM_UNPACK_ENCODE_BY_LITTEL_ENDIAN = 1,
    PSM_UNPACK_ENCODE_BY_BIG_ENDIAN    = 2,
}psm_unpack_coding_t;

typedef enum
{
    PSM_STATE_INIT = 0,
    PSM_STATE_BODY_BEFORE,
    PSM_STATE_BODY,
    PSM_STATE_BODY_AFTER,
}psm_state_t;

typedef struct psm psm_t;
struct psm
{
    uint8_t* buf;                     // 指向数据缓存
    uint32_t bufsize;                 // 数据缓存大小

    uint32_t wpos;                    // 写指针
    uint32_t rpos;                    // 读指针

    uint32_t match_start;

    psm_state_t state;

    int (*recv_callback)(psm_t* psm, const void* buf, uint32_t len);  // 数据回调函数

    uint8_t  delimiter[4];             // 协议尾分隔符
    uint32_t delimiter_bytes;          // 协议尾分隔符长度
    uint32_t delimiter_index;          // 协议尾分隔符匹配索引

    uint8_t  identifier[4];            // 协议头标识符
    uint32_t identifier_bytes;         // 协议头标识符长度
    uint32_t identifier_index;         // 协议头标识符匹配索引

    uint32_t body_offset;              // 主体数据偏移地址
    uint32_t body_length;              // 主体数据长度

    uint32_t length_field_offset;                 // 长度字段偏移地址
    uint32_t length_field_bytes;                  // 长度字段所占字节数
    psm_unpack_coding_t length_field_coding;      // 长度字节编码方式

    void* arg;                                    // 可用于携带附加参数
};

int psm_recv(psm_t* psm, const void* buf, uint32_t len);
int psm_recv_byte(psm_t* psm, uint8_t c);
void psm_reset(psm_t* psm);
int psm_unpack(psm_t* psm);
int psm_unpack_custom(psm_t* psm);

#ifdef __cplusplus
}
#endif

#endif /* PSM_H_ */
